


#include <iostream>
using namespace std;
int plain_text[8],ten_bit_key[10],ten_bit_key_after_applying_P10[10],P4[4],eight_bit_key_after_applying_initial_permutation[8],eight_bit_key_after_applying_expansion_permutation[8],ten_bit_key_after_applying_LS1[10],ten_bit_key_after_applying_LS2[10],Key1[8],Key2[8],P10[10],P8[8],initial_permutation[8],expansion_permutation[8],result_on_XOR_operation[8],S0_row,S0_column,S1_row,S1_column,result_from_S0_box,result_from_S1_box,four_bit_key_after_sbox[4],four_bits_of_ip[4],result_on_XOR_operation_after_P4[4],four_bit_key_after_applying_P4[4],cipher_text[8],decrypted_text[8],initial_permutation_inverse[8],* ptr,i,j;

int S0[4][4]={1,0,3,2,3,2,1,0,0,2,1,3,3,1,3,2} , S1[4][4]={0,1,2,3,2,0,1,3,3,0,1,0,2,1,0,3},binary_to_decimal[2][2]={0,1,2,3};


void apply_P10()
{
    for(i=0;i<10;i++)
        ten_bit_key_after_applying_P10[i]=ten_bit_key[P10[i]-1];
}


void apply_P4()
{
    for(i=0;i<4;i++)
        four_bit_key_after_applying_P4[i]=four_bit_key_after_sbox[P4[i]-1];
}

void apply_initial_permutation()
{
    for(i=0;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i]=plain_text[initial_permutation[i]-1];
}

void apply_initial_permutation_for_decryption()
{
    for(i=0;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i]=ten_bit_key[initial_permutation[i]-1];
}

void apply_initial_permutation_inverse()
{
    for(i=0;i<8;i++)
    {
        cipher_text[i]=eight_bit_key_after_applying_initial_permutation[initial_permutation_inverse[i]-1];
        decrypted_text[i]=cipher_text[i];
    }
}


void apply_expansion_permutation()
{
    for(i=0;i<8;i++)
        eight_bit_key_after_applying_expansion_permutation[i]=eight_bit_key_after_applying_initial_permutation[expansion_permutation[i]-1+4];
    
}

int * perform_XOR_operation(int temp_Key1[8],int temp_Key2[8])
{

    int result[8];
    
    for(i=0;i<8;i++)
        result[i]=temp_Key1[i]^temp_Key2[i];
    
    return result;
    
}

int * perform_XOR_operation_after_P4(int temp_Key1[4],int temp_Key2[4])
{
    
    int result[4];
    
    for(i=0;i<4;i++)
        result[i]=temp_Key1[i]^temp_Key2[i];
    
    return result;
    
}

void apply_LS1()
{

    for(i=0;i<4;i++)
    ten_bit_key_after_applying_LS1[i]=ten_bit_key_after_applying_P10[i+1];
    
    ten_bit_key_after_applying_LS1[4]=ten_bit_key_after_applying_P10[0];
    
    
    
    for(i=5;i<9;i++)
        ten_bit_key_after_applying_LS1[i]=ten_bit_key_after_applying_P10[i+1];
    
    ten_bit_key_after_applying_LS1[9]=ten_bit_key_after_applying_P10[5];
    
        
}

int * apply_P8(int temp[10],int size)
{
    int Key[size];
    
    for(i=0;i<size;i++)
        Key[i]=temp[P8[i]-1];
  
    return Key;
    
}

void apply_LS2()
{
    
    
    for(i=0;i<3;i++)
        ten_bit_key_after_applying_LS2[i]=ten_bit_key_after_applying_LS1[i+2];
    
    
    ten_bit_key_after_applying_LS2[3]=ten_bit_key_after_applying_LS1[0];
    ten_bit_key_after_applying_LS1[4]=ten_bit_key_after_applying_LS1[1];
    
    
    for(i=5;i<8;i++)
        ten_bit_key_after_applying_LS2[i]=ten_bit_key_after_applying_LS1[i+2];
    
    
    ten_bit_key_after_applying_LS2[8]=ten_bit_key_after_applying_LS1[5];
    ten_bit_key_after_applying_LS2[9]=ten_bit_key_after_applying_LS1[6];
    
}


int main() {
    
    
    
    cout<<"Enter the plain text\n";
    
    for(i=0;i<8;i++)
        cin>>plain_text[i];
    
    cout<<"Enter the ten bit key\n";

    for(i=0;i<10;i++)
        cin>>ten_bit_key[i];
    
    cout<<"Enter P10\n";

    for(i=0;i<10;i++)
        cin>>P10[i];
    
    cout<<"Enter the P8\n";

    
    for(i=0;i<8;i++)
        cin>>P8[i];
   
    cout<<"Enter the Initial Permutation\n";
    
    
    for(i=0;i<8;i++)
        cin>>initial_permutation[i];

    cout<<"Enter the Expansion Permutation\n";
    
    
    for(i=0;i<8;i++)
        cin>>expansion_permutation[i];

    cout<<"Enter P4\n";
    
    
    for(i=0;i<4;i++)
        cin>>P4[i];
    
    cout<<"Enter Initial Permutation Inverse\n";
    
    
    for(i=0;i<8;i++)
        cin>>initial_permutation_inverse[i];
    
    apply_P10();
    apply_LS1();
    ptr=apply_P8(ten_bit_key_after_applying_LS1,8);
    
    for(i=0;i<8;i++)
        Key1[i]=*(ptr+i);
    
    
   
    
    apply_LS2();
    ptr=apply_P8(ten_bit_key_after_applying_LS2,8);
    
    for(i=0;i<8;i++)
        Key2[i]=*(ptr+i);
    
    
    apply_initial_permutation();
    
    apply_expansion_permutation();
    
    ptr=perform_XOR_operation(eight_bit_key_after_applying_expansion_permutation,Key1);
    
    
    for(i=0;i<8;i++)
        result_on_XOR_operation[i]=*(ptr+i);
    
   
    S0_row=binary_to_decimal[result_on_XOR_operation[0]][result_on_XOR_operation[3]];
    S0_column=binary_to_decimal[result_on_XOR_operation[1]][result_on_XOR_operation[2]];
    S1_row=binary_to_decimal[result_on_XOR_operation[4]][result_on_XOR_operation[7]];
    S1_column=binary_to_decimal[result_on_XOR_operation[5]][result_on_XOR_operation[6]];
    
    result_from_S0_box=S0[S0_row][S0_column];
    result_from_S1_box=S1[S1_row][S1_column];
    
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S0_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[0]=i;
                four_bit_key_after_sbox[1]=j;
            }
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S1_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[2]=i;
                four_bit_key_after_sbox[3]=j;
            }
    
    apply_P4();
    
    
    for(i=0;i<4;i++)
        four_bits_of_ip[i]=eight_bit_key_after_applying_initial_permutation[i];
    
    ptr=perform_XOR_operation_after_P4(four_bit_key_after_applying_P4,four_bits_of_ip);
    
    for(i=0;i<4;i++)
        result_on_XOR_operation_after_P4[i]=*(ptr+i);
    

    
    for(i=4;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i-4]=eight_bit_key_after_applying_initial_permutation[i];
    
    for(i=4;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i]=result_on_XOR_operation_after_P4[i-4];
    
    apply_expansion_permutation();
    
    ptr= perform_XOR_operation(eight_bit_key_after_applying_expansion_permutation,Key2);
    
    for(i=0;i<8;i++)
        result_on_XOR_operation[i]=*(ptr+i);
    
    
    S0_row=binary_to_decimal[result_on_XOR_operation[0]][result_on_XOR_operation[3]];
    S0_column=binary_to_decimal[result_on_XOR_operation[1]][result_on_XOR_operation[2]];
    S1_row=binary_to_decimal[result_on_XOR_operation[4]][result_on_XOR_operation[7]];
    S1_column=binary_to_decimal[result_on_XOR_operation[5]][result_on_XOR_operation[6]];
    
    result_from_S0_box=S0[S0_row][S0_column];
    result_from_S1_box=S1[S1_row][S1_column];
    
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S0_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[0]=i;
                four_bit_key_after_sbox[1]=j;
            }
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S1_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[2]=i;
                four_bit_key_after_sbox[3]=j;
            }
    
    apply_P4();
    for(i=0;i<4;i++)
        four_bits_of_ip[i]=eight_bit_key_after_applying_initial_permutation[i];
    
    ptr=perform_XOR_operation_after_P4(four_bit_key_after_applying_P4,four_bits_of_ip);
    
    for(i=0;i<4;i++)
        result_on_XOR_operation_after_P4[i]=*(ptr+i);
    
   
    for(i=0;i<4;i++)
        eight_bit_key_after_applying_initial_permutation[i]=result_on_XOR_operation_after_P4[i];
    

    for(i=4;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i]=eight_bit_key_after_applying_initial_permutation[i];
    
    apply_initial_permutation_inverse();
    
    cout<<"\nCiphered Text is \n";
    for(i=0;i<8;i++)
        cout<<cipher_text[i];
    
    //-----------------------DECRYPTION STARTS HERE---------------
    
    for(i=0;i<8;i++)
        ten_bit_key[i]=cipher_text[i];
    
    apply_initial_permutation_for_decryption();
    apply_expansion_permutation();
    

    ptr=perform_XOR_operation(eight_bit_key_after_applying_expansion_permutation,Key2);
    
    
    for(i=0;i<8;i++)
        result_on_XOR_operation[i]=*(ptr+i);
    
    
    S0_row=binary_to_decimal[result_on_XOR_operation[0]][result_on_XOR_operation[3]];
    S0_column=binary_to_decimal[result_on_XOR_operation[1]][result_on_XOR_operation[2]];
    S1_row=binary_to_decimal[result_on_XOR_operation[4]][result_on_XOR_operation[7]];
    S1_column=binary_to_decimal[result_on_XOR_operation[5]][result_on_XOR_operation[6]];
    
    result_from_S0_box=S0[S0_row][S0_column];
    result_from_S1_box=S1[S1_row][S1_column];
    
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S0_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[0]=i;
                four_bit_key_after_sbox[1]=j;
            }
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S1_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[2]=i;
                four_bit_key_after_sbox[3]=j;
            }
    
    apply_P4();
    for(i=0;i<4;i++)
        four_bits_of_ip[i]=eight_bit_key_after_applying_initial_permutation[i];
    
    ptr=perform_XOR_operation_after_P4(four_bit_key_after_applying_P4,four_bits_of_ip);
    
    int temp_array[4];
    for(i=0;i<4;i++)
    {
        result_on_XOR_operation_after_P4[i]=*(ptr+i);
        temp_array[i]=result_on_XOR_operation_after_P4[i];
    }
    
    
    for(i=4;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i-4]=eight_bit_key_after_applying_initial_permutation[i];
    
    for(i=4;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i]=result_on_XOR_operation_after_P4[i-4];
    
    apply_expansion_permutation();
    
    ptr= perform_XOR_operation(eight_bit_key_after_applying_expansion_permutation,Key1);
    
    for(i=0;i<8;i++)
        result_on_XOR_operation[i]=*(ptr+i);
    
    S0_row=binary_to_decimal[result_on_XOR_operation[0]][result_on_XOR_operation[3]];
    S0_column=binary_to_decimal[result_on_XOR_operation[1]][result_on_XOR_operation[2]];
    S1_row=binary_to_decimal[result_on_XOR_operation[4]][result_on_XOR_operation[7]];
    S1_column=binary_to_decimal[result_on_XOR_operation[5]][result_on_XOR_operation[6]];
    
    result_from_S0_box=S0[S0_row][S0_column];
    result_from_S1_box=S1[S1_row][S1_column];
    
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S0_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[0]=i;
                four_bit_key_after_sbox[1]=j;
            }
    
    for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            if(result_from_S1_box==binary_to_decimal[i][j])
            {
                four_bit_key_after_sbox[2]=i;
                four_bit_key_after_sbox[3]=j;
            }
    
    apply_P4();
    for(i=0;i<4;i++)
        four_bits_of_ip[i]=eight_bit_key_after_applying_initial_permutation[i];
   
    
    ptr=perform_XOR_operation_after_P4(four_bit_key_after_applying_P4,four_bits_of_ip);
    
    for(i=0;i<4;i++)
        result_on_XOR_operation_after_P4[i]=*(ptr+i);
    
    
    for(i=0;i<4;i++)
        eight_bit_key_after_applying_initial_permutation[i]=result_on_XOR_operation_after_P4[i];
    
    
    for(i=4;i<8;i++)
        eight_bit_key_after_applying_initial_permutation[i]=temp_array[i-4];
    
    
    
    apply_initial_permutation_inverse();
    
    cout<<"\nDecrypted Text is \n";
    for(i=0;i<8;i++)
        cout<<decrypted_text[i];
    

    
    return 0;
}


/*
 
 OUTPUT:-

 Enter the plain text
 1 0 1 0 0 1 0 1
 Enter the ten bit key
 0 0 1 0 0 1 0 1 1 1
 Enter P10
 3 5 2 7 4 10 1 9 8 6
 Enter the P8
 6 3 7 4 8 5 10 9
 Enter the Initial Permutation
 2 6 3 1 4 8 5 7
 Enter the Expansion Permutation
 4 1 2 3 2 3 4 1
 Enter P4
 2 4 3 1
 Enter Initial Permutation Inverse
 4 1 3 5 7 2 8 6
 
 Ciphered Text is
 00110110
 Decrypted Text is
 10100101
 
 
 */

